package com.yunwaikeji.gy_tool_library.widget.recycler.image;

import android.content.Context;
import android.content.res.TypedArray;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.yunwaikeji.gy_tool_library.R;
import com.yunwaikeji.gy_tool_library.adapter.recycler.GYRecyclerAdapter;
import com.yunwaikeji.gy_tool_library.adapter.recycler.OnItemChildClickListener;
import com.yunwaikeji.gy_tool_library.adapter.recycler.OnItemClickListener;
import com.yunwaikeji.gy_tool_library.info.GYImageRecyclerInfo;
import com.yunwaikeji.gy_tool_library.utils.GYUiUtils;
import com.yunwaikeji.gy_tool_library.widget.recycler.GYRecyclerView;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class GYImageRecyclerView extends GYRecyclerView implements GYImageRecyclerInfo {
    public GYImageRecyclerView(@NonNull Context context) {
        super(context);
    }

    public GYImageRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public GYImageRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    private GYImageRecyclerAdapter imageAdapter;
    private GYImageRecyclerBuilder imageRecyclerBuilder;
    private GYImageUploadBuilder imageUploadBuilder;
    private OnItemClickListener onItemClickListener;
    private OnAddClickListener onAddClickListener;
    private OnUploadListener onUploadListener;

    public GYImageRecyclerAdapter getImageAdapter() {
        return imageAdapter;
    }

    public GYImageRecyclerBuilder getImageRecyclerBuilder() {
        return imageRecyclerBuilder;
    }

    public GYImageUploadBuilder getImageUploadBuilder() {
        return imageUploadBuilder;
    }

    public GYImageRecyclerView setOnItemClickListener(OnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
        return this;
    }

    public GYImageRecyclerView setOnAddClickListener(OnAddClickListener onAddClickListener) {
        this.onAddClickListener = onAddClickListener;
        return this;
    }

    public GYImageRecyclerView setOnUploadListener(OnUploadListener onUploadListener) {
        this.onUploadListener = onUploadListener;
        return this;
    }

    @Override
    public void initView(AttributeSet attributeSet) {
        super.initView(attributeSet);
        getRecyclerBuilder().setRecyclerDisplayStyle(DisplayStyle.GRID).build();
        imageRecyclerBuilder = new GYImageRecyclerBuilder(this);
        imageUploadBuilder = new GYImageUploadBuilder(this);
        imageAdapter = new GYImageRecyclerAdapter(this);
//        imageModelList = new ArrayList<>();
//        imageAdapter.setData(imageModelList);
        setAdapter(imageAdapter);

        int itemRadiusPx = WRAP_CONTENT;
        int deleteDrawableMarginPx = WRAP_CONTENT;
        int scaleType = 6;
        if (attributeSet != null) {
            TypedArray typedArray = getContext().obtainStyledAttributes(attributeSet, R.styleable.GYImageRecyclerView);
            imageRecyclerBuilder.setItemProportion(typedArray.getString(R.styleable.GYImageRecyclerView_itemProportion));
            itemRadiusPx = typedArray.getDimensionPixelSize(R.styleable.GYImageRecyclerView_itemRadius, itemRadiusPx);
            imageRecyclerBuilder.setItemRadiusLeftTopPx(typedArray.getDimensionPixelSize(R.styleable.GYImageRecyclerView_itemRadiusLeftTop, imageRecyclerBuilder.getItemRadiusLeftTopPx()));
            imageRecyclerBuilder.setItemRadiusRightTopPx(typedArray.getDimensionPixelSize(R.styleable.GYImageRecyclerView_itemRadiusRightTop, imageRecyclerBuilder.getItemRadiusRightTopPx()));
            imageRecyclerBuilder.setItemRadiusRightBottomPx(typedArray.getDimensionPixelSize(R.styleable.GYImageRecyclerView_itemRadiusRightBottom, imageRecyclerBuilder.getItemRadiusRightBottomPx()));
            imageRecyclerBuilder.setItemRadiusLeftBottomPx(typedArray.getDimensionPixelSize(R.styleable.GYImageRecyclerView_itemRadiusLeftBottom, imageRecyclerBuilder.getItemRadiusLeftBottomPx()));
            imageRecyclerBuilder.setItemWidthPx(typedArray.getDimensionPixelSize(R.styleable.GYImageRecyclerView_itemWidth, imageRecyclerBuilder.getItemWidthPx()));
            imageRecyclerBuilder.setItemHeightPx(typedArray.getDimensionPixelSize(R.styleable.GYImageRecyclerView_itemHeight, imageRecyclerBuilder.getItemHeightPx()));
            imageRecyclerBuilder.setEdit(typedArray.getBoolean(R.styleable.GYImageRecyclerView_isEdit, imageRecyclerBuilder.isEdit()));
            imageRecyclerBuilder.setAddDrawable(typedArray.getDrawable(R.styleable.GYImageRecyclerView_addDrawable));
            imageRecyclerBuilder.setAddDrawableWidth(typedArray.getDimension(R.styleable.GYImageRecyclerView_addDrawableWidth, imageRecyclerBuilder.getAddDrawableWidth()));
            imageRecyclerBuilder.setAddDrawableHeight(typedArray.getDimension(R.styleable.GYImageRecyclerView_addDrawableHeight, imageRecyclerBuilder.getAddDrawableHeight()));
            imageRecyclerBuilder.setAddDrawable(typedArray.getDrawable(R.styleable.GYImageRecyclerView_addDrawable));
            imageRecyclerBuilder.setDeleteLocation(typedArray.getInteger(R.styleable.GYImageRecyclerView_deleteLocation, imageRecyclerBuilder.getDeleteLocation()));
            imageRecyclerBuilder.setDeleteDrawable(typedArray.getDrawable(R.styleable.GYImageRecyclerView_deleteDrawable));
            imageRecyclerBuilder.setDeleteDrawableWidthPx(typedArray.getDimensionPixelSize(R.styleable.GYImageRecyclerView_deleteDrawableWidth, imageRecyclerBuilder.getDeleteDrawableWidthPx()));
            imageRecyclerBuilder.setDeleteDrawableHeightPx(typedArray.getDimensionPixelSize(R.styleable.GYImageRecyclerView_deleteDrawableHeight, imageRecyclerBuilder.getDeleteDrawableHeightPx()));
            deleteDrawableMarginPx = typedArray.getDimensionPixelSize(R.styleable.GYImageRecyclerView_deleteDrawableMargin, deleteDrawableMarginPx);
            imageRecyclerBuilder.setDeleteDrawableMarginLeftPx(typedArray.getDimensionPixelSize(R.styleable.GYImageRecyclerView_deleteDrawableMarginLeft, imageRecyclerBuilder.getDeleteDrawableMarginLeftPx()));
            imageRecyclerBuilder.setDeleteDrawableMarginTopPx(typedArray.getDimensionPixelSize(R.styleable.GYImageRecyclerView_deleteDrawableMarginTop, imageRecyclerBuilder.getDeleteDrawableMarginTopPx()));
            imageRecyclerBuilder.setDeleteDrawableMarginRightPx(typedArray.getDimensionPixelSize(R.styleable.GYImageRecyclerView_deleteDrawableMarginRight, imageRecyclerBuilder.getDeleteDrawableMarginRightPx()));
            imageRecyclerBuilder.setDeleteDrawableMarginBottomPx(typedArray.getDimensionPixelSize(R.styleable.GYImageRecyclerView_deleteDrawableMarginBottom, imageRecyclerBuilder.getDeleteDrawableMarginBottomPx()));
            imageRecyclerBuilder.setMaxImageNumber(typedArray.getInteger(R.styleable.GYImageRecyclerView_maxImageNumber, imageRecyclerBuilder.getMaxImageNumber()));
            imageRecyclerBuilder.setImageEdgeWidth(typedArray.getDimension(R.styleable.GYImageRecyclerView_imageEdgeWidth, imageRecyclerBuilder.getImageEdgeWidth()));
            imageRecyclerBuilder.setImageEdgeColor(typedArray.getColor(R.styleable.GYImageRecyclerView_imageEdgeColor, imageRecyclerBuilder.getImageEdgeColor()));
            imageRecyclerBuilder.setImageEdgeOver(typedArray.getBoolean(R.styleable.GYImageRecyclerView_imageEdgeOver, imageRecyclerBuilder.isImageEdgeOver()));
            imageRecyclerBuilder.setAddEdgeWidth(typedArray.getDimension(R.styleable.GYImageRecyclerView_addEdgeWidth, imageRecyclerBuilder.getAddEdgeWidth()));
            imageRecyclerBuilder.setAddEdgeColor(typedArray.getColor(R.styleable.GYImageRecyclerView_addEdgeColor, imageRecyclerBuilder.getAddEdgeColor()));
            imageRecyclerBuilder.setAddEdgeOver(typedArray.getBoolean(R.styleable.GYImageRecyclerView_addEdgeOver, imageRecyclerBuilder.isAddEdgeOver()));
            imageRecyclerBuilder.setProgressShow(typedArray.getBoolean(R.styleable.GYImageRecyclerView_progressShow, imageRecyclerBuilder.isProgressShow()));
            imageRecyclerBuilder.setStartDrawable(typedArray.getDrawable(R.styleable.GYImageRecyclerView_startDrawable));
            imageRecyclerBuilder.setLoadingDrawable(typedArray.getDrawable(R.styleable.GYImageRecyclerView_loadingDrawable));
            imageRecyclerBuilder.setErrorDrawable(typedArray.getDrawable(R.styleable.GYImageRecyclerView_errorDrawable));
            imageRecyclerBuilder.setAddLocation(typedArray.getInteger(R.styleable.GYImageRecyclerView_addLocation, imageRecyclerBuilder.getAddLocation()));
            scaleType = typedArray.getInteger(R.styleable.GYImageRecyclerView_android_scaleType, scaleType);
            typedArray.recycle();
        }
        if (itemRadiusPx != WRAP_CONTENT) {
            imageRecyclerBuilder.setItemRadiusLeftTopPx(itemRadiusPx);
            imageRecyclerBuilder.setItemRadiusRightTopPx(itemRadiusPx);
            imageRecyclerBuilder.setItemRadiusRightBottomPx(itemRadiusPx);
            imageRecyclerBuilder.setItemRadiusLeftBottomPx(itemRadiusPx);
        }
        if (deleteDrawableMarginPx != WRAP_CONTENT) {
            imageRecyclerBuilder.setDeleteDrawableMarginLeftPx(deleteDrawableMarginPx);
            imageRecyclerBuilder.setDeleteDrawableMarginTopPx(deleteDrawableMarginPx);
            imageRecyclerBuilder.setDeleteDrawableMarginRightPx(deleteDrawableMarginPx);
            imageRecyclerBuilder.setDeleteDrawableMarginBottomPx(deleteDrawableMarginPx);
        }
        imageRecyclerBuilder.setScaleType(getScaleType(scaleType));
        imageRecyclerBuilder.build();
        imageAdapter.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(@NonNull GYRecyclerAdapter<?, ?> adapter, @NonNull View view, int position) {
                if (imageAdapter.getData().get(position).getPathType() == PathType.ADD) {
                    if (onAddClickListener != null) {
                        onAddClickListener.onAddClick();
                    }
                } else {
                    int position1 = position;
                    if (!imageAdapter.getData().isEmpty() && imageAdapter.getData().get(0).getPathType() == PathType.ADD) {
                        position1 = position - 1;
                    }
                    if (onItemClickListener != null) {
                        onItemClickListener.onItemClick(adapter, view, position1);
                    }
                }
            }
        });
        imageAdapter.setOnItemChildClickListener(new OnItemChildClickListener() {
            @Override
            public void onItemChildClick(@NonNull GYRecyclerAdapter<?, ?> adapter, @NonNull View view, int position) {
                if (view.getId() == R.id.delImg) {
                    if (onDeleteClickListener == null) {
                        remove(position);
                    } else {
                        if (!onDeleteClickListener.onDeleteClick(position)) {
                            remove(position);
                        }
                    }
                    if (!hasAddModel()) {
                        addAddModel();
                    }
                    onItemChange();
                }
            }
        });
//        ((SimpleItemAnimator) getItemAnimator()).setSupportsChangeAnimations(false);
    }

    private ImageView.ScaleType getScaleType(int scaleType) {
        switch (scaleType) {
            case 1:
                return ImageView.ScaleType.FIT_XY;
            case 2:
                return ImageView.ScaleType.FIT_START;
            case 3:
                return ImageView.ScaleType.FIT_CENTER;
            case 4:
                return ImageView.ScaleType.FIT_END;
            case 5:
                return ImageView.ScaleType.CENTER;
            case 6:
                return ImageView.ScaleType.CENTER_CROP;
            case 7:
                return ImageView.ScaleType.CENTER_INSIDE;
            case 0:
            default:
                return ImageView.ScaleType.MATRIX;
        }
    }

    private OnDeleteClickListener onDeleteClickListener;

    public GYImageRecyclerView setOnDeleteClickListener(OnDeleteClickListener onDeleteClickListener) {
        this.onDeleteClickListener = onDeleteClickListener;
        return this;
    }

    public OnDeleteClickListener getOnDeleteClickListener() {
        return onDeleteClickListener;
    }

    public List<GYImageRecyclerModel> getModelList() {
        List<GYImageRecyclerModel> imageModelList = new ArrayList<>();
        for (GYImageRecyclerModel imageModel : imageAdapter.getData()) {
            if (imageModel.getPathType() != PathType.ADD) {
                imageModelList.add(imageModel);
            }
        }
        return imageModelList;
    }

    public List<String> getUrlList() {
        List<String> urlList = new ArrayList<>();
        List<GYImageRecyclerModel> modelList = getModelList();
        for (GYImageRecyclerModel model : modelList) {
            urlList.add(model.getUrl());
        }
        return urlList;
    }

    public List<String> getLoadPathList() {
        List<String> urlList = new ArrayList<>();
        List<GYImageRecyclerModel> modelList = getModelList();
        for (GYImageRecyclerModel model : modelList) {
            urlList.add(model.getLoadPath());
        }
        return urlList;
    }

    public List<String> getLocalPathList() {
        List<String> urlList = new ArrayList<>();
        List<GYImageRecyclerModel> modelList = getModelList();
        for (GYImageRecyclerModel model : modelList) {
            urlList.add(model.getLocalPath());
        }
        return urlList;
    }

    public GYImageRecyclerView addModel(List<GYImageRecyclerModel> modelList) {
        int max = imageRecyclerBuilder.getMaxImageNumber();
        if (!imageRecyclerBuilder.isEdit()) {
            removeAddModel();
        }
        if (max != WRAP_CONTENT && getModelList().size() + modelList.size() >= max) {
            removeAddModel();
            if (!modelList.isEmpty()) {
                List<GYImageRecyclerModel> addList = modelList.subList(0, max - imageAdapter.getData().size());
                imageAdapter.addData(addList);
            }
        } else {
            if (hasAddModel() && (imageRecyclerBuilder.getAddLocation() == AddLocation.END || imageRecyclerBuilder.getAddLocation() == AddLocation.ALL)) {
                int index = imageAdapter.getData().size() - 1;
                for (GYImageRecyclerModel model : modelList) {
                    imageAdapter.getData().add(index, model);
                    index++;
                }
            } else {
                imageAdapter.addData(modelList);
            }
            if (!hasAddModel() && imageRecyclerBuilder.isEdit()) {
                addAddModel();
            }
        }
        notifyDataSetChanged();
        return onItemChange();
    }

    public GYImageRecyclerView addModel(GYImageRecyclerModel... models) {
        return addModel(Arrays.asList(models));
    }

    public GYImageRecyclerView setModel(List<GYImageRecyclerModel> modelList) {
        imageAdapter.getData().clear();
        return addModel(modelList);
    }

    public GYImageRecyclerView setModel(GYImageRecyclerModel... models) {
        return setModel(Arrays.asList(models));
    }

    public GYImageRecyclerView addLocalPath(boolean toUpload, List<String> pathList) {
        List<GYImageRecyclerModel> imageModelList = new ArrayList<>();
        for (String path : pathList) {
            imageModelList.add(new GYImageRecyclerModel()
                    .setToUpload(toUpload)
                    .setLoadPath(path));
        }
        return addModel(imageModelList);
    }

    public GYImageRecyclerView addLocalPath(List<String> pathList) {
        return addLocalPath(false, pathList);
    }

    public GYImageRecyclerView addLocalPath(boolean toUpload, String... paths) {
        return addLocalPath(toUpload, Arrays.asList(paths));
    }

    public GYImageRecyclerView addLocalPath(String... paths) {
        return addLocalPath(false, paths);
    }

    public GYImageRecyclerView setLocalPath(boolean toUpload, List<String> pathList) {
        imageAdapter.getData().clear();
        return addLocalPath(toUpload, pathList);
    }

    public GYImageRecyclerView setLocalPath(List<String> pathList) {
        return setLocalPath(false, pathList);
    }

    public GYImageRecyclerView setLocalPath(boolean toUpload, String... paths) {
        return setLocalPath(toUpload, Arrays.asList(paths));
    }

    public GYImageRecyclerView setLocalPath(String... paths) {
        return setLocalPath(false, Arrays.asList(paths));
    }

    public GYImageRecyclerView addLoadPath(List<String> loadPathList) {
        List<GYImageRecyclerModel> modelList = new ArrayList<>();
        for (String loadPath : loadPathList) {
            GYImageRecyclerModel model = new GYImageRecyclerModel();
            model.setLoadPath(loadPath);
            modelList.add(model);
        }
        return addModel(modelList);
    }

    public GYImageRecyclerView addLoadPath(String... loadPaths) {
        return addLoadPath(Arrays.asList(loadPaths));
    }

    public GYImageRecyclerView setLoadPath(List<String> loadPathList) {
        imageAdapter.getData().clear();
        return addLoadPath(loadPathList);
    }

    public GYImageRecyclerView setLoadPath(String... loadPaths) {
        return setLoadPath(Arrays.asList(loadPaths));
    }

    public GYImageRecyclerView notifyDataSetChanged() {
        GYUiUtils.runOnUiThread(() -> imageAdapter.notifyDataSetChanged());
        return this;
    }

    private GYImageRecyclerModel newAddModel() {
        return new GYImageRecyclerModel().setPathType(PathType.ADD);
    }

    private int getAddModelCount() {
        int count = 0;
        for (GYImageRecyclerModel model : imageAdapter.getData()) {
            if (model.getPathType() == PathType.ADD) {
                count++;
            }
        }
        return count;
    }

    private boolean hasAddModel() {
        return getAddModelCount() > 0;
    }

    private void addAddModel() {
        int addLocation = getImageRecyclerBuilder().getAddLocation();
        if (addLocation == AddLocation.START) {
            imageAdapter.getData().add(0, newAddModel());
            notifyDataSetChanged();
        } else if (addLocation == AddLocation.END) {
            imageAdapter.addData(newAddModel());
        } else {
            imageAdapter.getData().add(0, newAddModel());
            imageAdapter.addData(newAddModel());
            notifyDataSetChanged();
        }
    }

    private void removeAddModel() {
        for (int i = imageAdapter.getData().size() - 1; i >= 0; i--) {
            if (imageAdapter.getData().get(i).getPathType() == PathType.ADD) {
                imageAdapter.getData().remove(i);
                imageAdapter.notifyItemRemoved(i);
                imageAdapter.notifyItemRangeRemoved(i, imageAdapter.getData().size() - i);
            }
        }
    }

    public GYImageRecyclerView startAllUpload() {
        for (int i = 0; i < imageAdapter.getData().size(); i++) {
            GYImageRecyclerModel imageModel = imageAdapter.getData().get(i);
            if (imageModel.getPathType() != PathType.ADD) {
                imageAdapter.getData().get(i).setToUpload(true);
                imageAdapter.notifyItemChanged(i);
            }
        }
        return this;
    }

    public GYImageRecyclerView startUpload() {
        for (int i = 0; i < imageAdapter.getData().size(); i++) {
            GYImageRecyclerModel imageModel = imageAdapter.getData().get(i);
            if (imageModel.getPathType() != PathType.ADD) {
                imageAdapter.getData().get(i).setToUpload(TextUtils.isEmpty(imageModel.getUrl()));
                imageAdapter.notifyItemChanged(i);
            }
        }
        return this;
    }

    public boolean isAllUploaded() {
        for (GYImageRecyclerModel model : getModelList()) {
            if (TextUtils.isEmpty(model.getUrl())) {
                return false;
            }
        }
        return true;
    }

    public GYImageRecyclerView remove(int position) {
        imageAdapter.getData().remove(position);
        imageAdapter.notifyItemRemoved(position);
        imageAdapter.notifyItemRangeRemoved(position, imageAdapter.getData().size() - position);
        return this;
    }

    public GYImageRecyclerView clear() {
        imageAdapter.getData().clear();
        setModel();
        return this;
    }

    private OnItemChangeListener onItemChangeListener;

    public GYImageRecyclerView setOnItemChangeListener(OnItemChangeListener onItemChangeListener) {
        this.onItemChangeListener = onItemChangeListener;
        return this;
    }

    public OnItemChangeListener getOnItemChangeListener() {
        return onItemChangeListener;
    }

    private GYImageRecyclerView onItemChange() {
        if (onItemChangeListener != null) {
            onItemChangeListener.onItemChange();
        }
        return this;
    }
}
